@use 'sass:map';
@use '@material/slider/slider' as mdc-slider;
@use '@material/slider/slider-theme' as mdc-slider-theme;
@use '@material/theme/custom-properties' as mdc-custom-properties;
@use '../core/tokens/m2/mat/slider' as m2-mat-slider;
@use '../core/tokens/m2/mdc/slider' as m2-mdc-slider;
@use '../core/tokens/token-utils';

$mat-slider-min-size: 128px !default;
$mat-slider-horizontal-margin: 8px !default;

@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
  $mdc-slider-token-slots: m2-mdc-slider.get-token-slots();

  // Add MDC slider static styles.
  @include mdc-slider.static-styles();

  .mat-mdc-slider {
    // Add the official slots for the MDC slider.
    @include mdc-slider-theme.theme-styles(map.merge($mdc-slider-token-slots, (
      // MDC emits the incorrect box-shadow on .mdc-slider__thumb-knob, so we
      // emit the elevation slot ourselves instead.
      handle-elevation: null,
      handle-shadow-color: null,
    )));

    // Emit the elevation slot directly on the slider thumb
    .mdc-slider__thumb-knob {
      @include token-utils.use-tokens(
        m2-mdc-slider.$prefix, $mdc-slider-token-slots) {
        @include token-utils.create-token-slot(box-shadow, handle-elevation);
      }
    }

    display: inline-block;
    box-sizing: border-box;
    outline: none;
    vertical-align: middle;
    margin: {
      left: $mat-slider-horizontal-margin;
      right: $mat-slider-horizontal-margin;
    }

    // Unset the default "width" property from the MDC slider class. We don't want
    // the slider to automatically expand horizontally for backwards compatibility.
    width: auto;
    min-width: $mat-slider-min-size - (2 * $mat-slider-horizontal-margin);
    -webkit-tap-highlight-color: transparent;

    .mdc-slider__input {
      // It's common for apps to globally set `box-sizing: border-box` which messes up our
      // measurements. Explicitly set `content-box` to avoid issues like #26246.
      box-sizing: content-box;
      pointer-events: auto;

      &.mat-mdc-slider-input-no-pointer-events {
        pointer-events: none;
      }

      &.mat-slider__right-input {
        left: auto;
        right: 0;
      }
    }

    .mdc-slider__thumb,
    .mdc-slider__track--active_fill {
      transition-duration: 0ms;
    }
    &.mat-mdc-slider-with-animation {
      .mdc-slider__thumb,
      .mdc-slider__track--active_fill {
        transition-duration: 80ms;
      }
    }

    // We need to repeat these styles to override discrete slider styling.
    &.mdc-slider--discrete {
      .mdc-slider__thumb,
      .mdc-slider__track--active_fill {
        transition-duration: 0ms;
      }
    }
    &.mat-mdc-slider-with-animation {
      .mdc-slider__thumb,
      .mdc-slider__track--active_fill {
        transition-duration: 80ms;
      }
    }

    .mdc-slider__track,
    .mdc-slider__thumb {
      pointer-events: none;
    }

    // Add slots for custom Angular Material slider tokens.
    @include token-utils.use-tokens(m2-mat-slider.$prefix, m2-mat-slider.get-token-slots()) {
      .mdc-slider__value-indicator-container {
        @include token-utils.create-token-slot(transform, value-indicator-container-transform);
      }

      .mdc-slider__value-indicator {
        @include token-utils.create-token-slot(width, value-indicator-width);
        @include token-utils.create-token-slot(height, value-indicator-height);
        @include token-utils.create-token-slot(padding, value-indicator-padding);
        @include token-utils.create-token-slot(opacity, value-indicator-opacity);
        @include token-utils.create-token-slot(border-radius, value-indicator-border-radius);

        &::before {
          @include token-utils.create-token-slot(display, value-indicator-caret-display);
        }
      }

      .mdc-slider__value-indicator-text {
        @include token-utils.create-token-slot(width, value-indicator-width);
        @include token-utils.create-token-slot(transform, value-indicator-text-transform);
      }

      // The `.mat-ripple` wrapper here is redundant, but we need it to
      // increase the specificity due to how some styles are setup in g3.
      .mat-ripple {
        // These ripple colors are custom so we have to introduce our own tokens.
        .mat-ripple-element {
          @include token-utils.create-token-slot(background-color, ripple-color);
        }

        .mat-mdc-slider-hover-ripple {
          @include token-utils.create-token-slot(background-color, hover-state-layer-color);
        }

        .mat-mdc-slider-focus-ripple,
        .mat-mdc-slider-active-ripple {
          @include token-utils.create-token-slot(background-color, focus-state-layer-color);
        }
      }
    }

    &._mat-animation-noopable {
      &.mdc-slider--discrete .mdc-slider__thumb,
      &.mdc-slider--discrete .mdc-slider__track--active_fill,
      .mdc-slider__value-indicator {
        transition: none;
      }
    }

    // Slider components have to set `border-radius: 50%` in order to support density scaling
    // which will clip a square focus indicator so we have to turn it into a circle.
    .mat-mdc-focus-indicator::before {
      border-radius: 50%;
    }

    // Stop parent word-break from altering
    // the word-break of the value indicator.
    .mdc-slider__value-indicator {
      word-break: normal;
    }

    .mdc-slider__value-indicator-text {
      text-align: center;
    }
  }
  // In the MDC slider the focus indicator is inside the thumb.
  .mdc-slider__thumb--focused .mat-mdc-focus-indicator::before {
    content: '';
  }
}
